package com.alinesno.cloud.common.web.base.advice;

import java.lang.annotation.Annotation;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.alinesno.cloud.common.core.context.ApplicationContextProvider;
import com.alinesno.cloud.common.web.base.advice.plugins.PluginRegistry;
import com.alinesno.cloud.common.web.base.bean.DatatablesPageBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.type.TypeFactory;

/**
 * 数据切面
 * @author LuoAnDong
 * @since 2018年9月23日 下午6:28:15
 */
@Order(0)
@ControllerAdvice
public class DatagridResponseBodyAdvice implements ResponseBodyAdvice<DatatablesPageBean> {

	// 日志记录
	private final static Logger log = LoggerFactory.getLogger(DatagridResponseBodyAdvice.class);
	
	private ObjectMapper objectMapper = new ObjectMapper();
	private TypeFactory typeFactory = objectMapper.getTypeFactory();
	
	/**
	 * 拦截数据
	 */
	@Override
	public DatatablesPageBean beforeBodyWrite(DatatablesPageBean baseGridData, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> classes, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
		
		Object dataObject = baseGridData.getData(); 
		
		if(dataObject == null) {
			return baseGridData ; 
		}
		
		try {
			TranslateCode convertCode = methodParameter.getMethod().getAnnotation(TranslateCode.class);
			String pluginName = convertCode.plugin() ; 
			
			if(dataObject instanceof List) {
				String dataObjectStr = objectMapper.writeValueAsString(dataObject) ; 
				List<ObjectNode> dataObjectList = objectMapper.readValue(dataObjectStr, typeFactory.constructCollectionType(List.class, ObjectNode.class));
				
				for(ObjectNode node : dataObjectList) {
					
					log.debug("PluginRegistry.query() = {}" , PluginRegistry.query());
					
					for(Class<?> c : PluginRegistry.query()) {
						TranslatePlugin plugin = (TranslatePlugin) ApplicationContextProvider.getBean(c) ; 
						plugin.translate(node, convertCode); 
						
						if(StringUtils.isNotBlank(pluginName)) {
							TranslatePlugin selfP = (TranslatePlugin) ApplicationContextProvider.getBean(pluginName) ; 
							selfP.translate(node, convertCode);
						}
					}
					
				}
				baseGridData.setData(dataObjectList);	
			}
		} catch (Exception e) {
			log.error("代码转换异常:{}" , e);
		}
		
		return baseGridData;
	}

	@Override
	public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> classes) {
		TranslateCode convertCode = methodParameter.getMethod().getAnnotation(TranslateCode.class);

		if (log.isDebugEnabled()) {
			log.debug("convertCode = {}", convertCode);
			Annotation[] annotations = methodParameter.getMethodAnnotations();
			for (Annotation a : annotations) {
				log.debug("annotation = {}", a);
			}
		}

		return convertCode == null ? false : true;
	}

}